<template>
  <div class="comp-control" :class="layout + ' ' + componentInfo.is">
  <div class="label-box" :style="{ width : labelWidth}">{{label}}</div>
  <!-- 远程搜索 -->
  <div v-if="componentInfo.is === 'remote-select'" class="control-box" >
    <div v-show="valueSelf=== '' && !isFocus" class="placeholder">请输入关键字</div>
    <a-select
      show-search
      :value="valueSelf"
      style="width: 180px;"
      :default-active-first-option="true"
      :show-arrow="true"
      :filter-option="false"
      :not-found-content="null"
      :loading="isLoading"
      @focus="isFocus = true"
      @blur="isFocus = false"
      @search="handleSearch"
      @change="handleChange"
    >
      <a-select-option v-for="d in optionData" :key="d.value">
        {{ d.text }}
      </a-select-option>
      <!-- 加载更多 -->
      <a-select-option v-if="totalElements > 0 && (totalElements > optionData.length) && !isLoading" 
        :key="'--------'" 
        class="more-option" 
        :disabled="true"> 
        <a-button size="small" @click="addMore">加载更多...</a-button> 
      </a-select-option>
    </a-select>
  </div>
  <div v-else class="control-box">
    <component  :is="componentInfo.is" v-bind="prop" v-model="valueSelf"  @input="onInput" @change="onChange">
      <template v-if="componentInfo.sub">
        <component :is="componentInfo.sub" v-for="(item, i) in options" :key="i" :value="item.value" >{{item.label}}</component>
      </template>
    </component>
  </div>
  </div>
</template>
<script lang="ts">
import { tcolumnQueryValuesByPage } from '@/api/visualization'
import Vue from 'vue'
import KV from '../form/kv'
import rangeDay from '../form/rangeDay.vue'
import rangeMonth from '../form/rangeMonth.vue'
import rangeYear from '../form/rangeYear.vue'
import { componentTypeEnum, controlLayoutEnum, controlTypeEnum } from '../vueGridLayout/interfate/grid-Item-data-inteface'


const controlMap = {
  [`${componentTypeEnum.radio}`]: {
    is: 'a-radio-group',
    sub: 'a-radio',
    subKey: 'options'
  },
  [`${componentTypeEnum.checkbox}`]: {
    is: 'a-checkbox-group',
    sub: 'a-checkbox',
    subKey: 'options'
  },
  [`${componentTypeEnum.remoteSelect}`]: {
    is: 'remote-select',
    sub: 'a-select-option',
    subKey: 'options'
  },
  [`${componentTypeEnum.select}`]: {
    is: 'a-select',
    sub: 'a-select-option',
    subKey: 'options'
  },
  [`${componentTypeEnum.rangeDay}`]: {
    is:  'range-day' // 'a-range-picker'
  },
  [`${componentTypeEnum.rangeMonth}`]: {
    is: 'range-month'
  },
  [`${componentTypeEnum.rangeYear}`]: {
    is: 'range-year'
  }
}

/**
 * 控件通用组件 目前支持单选、多选、下拉、日期范围、月范围、年范围
 */
export default Vue.extend({
  components: {
    rangeYear,
    rangeMonth,
    rangeDay
  },
  props: {
    gridItem:{
      type: Object,
      default(){
        return null
      }
    },
    fieldConfig:{
      type: Object,
      default(){
        return {}
      }
    },
    layout: {
      type: String,
      default(){
        return controlLayoutEnum.vertical
      }
    },
    labelWidth: {
      type: String,
      default(){
        return '80px'
      }
    },
    prop: {
      type: Object,
      default(){
        return {}
      }
    },
    label:{
      type: String,
      default(){
        return ''
      }
    },
    options: {
      type: Array,
      default(){
        return []
      }
    },
    controlType:{
      type: String,
      default(){
        return ''
      }
    },
    value: {
      type: [String,Number,Array],
      default(){
        return ''
      }
    }

  },
  data(){
    const defaultValue:KV = {
      isFocus: false,
      isLoading:false,
      currentPage: 1,
      keywords: '',
      valueSelf: '',
      totalElements: 0,
      pageSize: 50,
      optionData: []
    }
    return defaultValue
  },
  computed: {
    componentInfo(){
      return (controlMap as any)[(this as any).controlType]
    }
  },
  watch:{
    value: {
      handler(newValue:any, oldValue:any){
        if(newValue !== oldValue){
          const that  = this as any
          that.valueSelf = that.value
        }
      }
    }
  },
  created(){
    const that  = this as any
    that.valueSelf = that.value
  },
  methods: {
    fetch(keywords:string, callback:Function){
      const that = this as any
      const tableName = this.gridItem.tableName || ''
      const column = this.fieldConfig.column as any
      if(tableName && column) {
        that.isLoading = true
        tcolumnQueryValuesByPage({
          data: {
              curPage: that.currentPage as number || 1,
              pageSize: that.pageSize || 50,
              search: keywords.trim() || '',
              table: tableName,
              name: column.value
          }
        }).then(response => {
          that.isLoading = false
          if(response.data.code === 100) {
            that.totalElements = response.data.result.totalElements
            const data = response.data.result.data as Array<string>
            const options:Array<KV> = []
            data.forEach((value:string) => {
              options.push({
                text: value,
                value
              })
            })
            callback(options)
          }
        }).catch(()=> {
          that.isLoading = false
        })
      }
    },
    addMore(){
      this.currentPage += 1
      this.fetch(this.keywords, (data:Array<any>) => {
        this.optionData.push(...data) 
      })
    },
    handleSearch(value:string) {
      const that = this as any
      that.keywords = value
      that.currentPage = 1
      that.optionData = []
      this.fetch(value, (data:Array<any>) => {
        this.optionData = data
      })
    },
    handleChange(value:string) {
      this.valueSelf = value
      this.$emit('input', value)
      this.$nextTick(()=>{
        this.$emit('change', value)
      })
    },
    onInput(value:any){
      this.$emit('input', value)
      this.$nextTick(()=>{
        this.$emit('change', value)
      })
    },
    onChange(){
      const that  = this as any
      if(that.controlType === controlTypeEnum.select){
        const valueSelf = that.valueSelf as any
        if(that.value !== valueSelf){
          this.$emit('input', valueSelf)
          this.$nextTick(()=>{
            this.$emit('change', valueSelf)
          })
        }
      }
    }
  }
})
</script>
<style lang="less" scoped>
.label-box {
  color: #5d637e;
  font-size: 14px;
  font-weight: 500;
  height: 20px;
  letter-spacing: 1px;
  line-height: 20px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.control-box {
  display: block;
  height: auto;
  width: 100%;

  /deep/ .ant-radio-group,
  /deep/ .ant-radio-wrapper,
  /deep/ .ant-checkbox-wrapper {
    color: #373b52;
    line-height: 20px;
  }

  /deep/ .ant-radio-wrapper,
  /deep/ .ant-checkbox-wrapper {
    margin-top: 4px;
  }

  /deep/ .ant-select {
    min-width: 140px;
  }
}

.comp-control {
  display: block;
  padding: 0 20px;

  &.horizontal {
    align-items: left;
    display: flex;
    flex-flow: row;
    padding-bottom: 8px;

    .label-box {
      color: #5d637e;
      font-weight: 500;
      height: 32px;
      letter-spacing: 1px;
      line-height: 32px;
      
  
    }

    .control-box {
      flex: 1;

      .ant-checkbox-group {
        padding-top: 2px;
      }
    }
  }

  &.vertical {
    margin-bottom: 12px;

    .label-box {
      color: #5d637e;
      font-weight: 500;
      height: 20px;
      letter-spacing: 1px;
      line-height: 16px;
      width: 100% !important;
    }
  }

  /deep/ .spliter {
    height: 30px;
    line-height: 30px;
  }
}

.placeholder {
  color: #999;
  font-size: 12px;
  line-height: 32px;
  padding-left: 14px;
  pointer-events: none;
  position: absolute;
  z-index: 1;
}
</style>